<template>
  <div class="container">
    <el-container class="el-container">
      <el-main class="nuxt-main" :class="{ isApp: isApp }">
        <header-app v-if="isApp"></header-app>
        <header-web v-if="isPC" @show="onShow"></header-web>
        <div ref="nuxtBody" class="nuxt-body">
          <!-- 生产环境打开keep-alive，开发环境暂时关闭，否则会影响热更新 -->
          <nuxt v-if="isRouterAlive"></nuxt>
          <footer-app v-if="isApp" @toTop="scrollToTop"></footer-app>
          <footer-web v-if="isPC"></footer-web>
          <div v-if="isPC" class="totop" :class="{ active: showTotop }" @click="scrollToTop">
            <i class="el-icon-upload2"></i>
          </div>
        </div>
      </el-main>
    </el-container>
    <registered-dialog-web
      v-if="visible"
      :defaultType="type"
      @hide="visible = false"
    ></registered-dialog-web>
  </div>
</template>

<script>
import { mapMutations, mapState } from 'vuex'

import Panles from '@/container/default/importComponents'

import { MIN_CLIENT_WIDTH } from '@/const/platform'
import { debounce } from '@/utils/index.js'

export default {
  components: {
    ...Panles,
  },
  // 用于刷新当前页面
  provide() {
    return {
      reload: this.reload,
    }
  },
  middleware: ['auth', 'lang'],
  data() {
    return {
      isRouterAlive: true,
      debounceFunc: null,
      scrollFunc: null,
      visible: false,
      showTotop: false,
    }
  },
  head() {
    const lang = this.$store.state.lang

    // 字典有配置标题，则显示配置标题
    const head = {}

    if (lang) {
      head.title = lang === 'zh' ? '硕腾科技' : 'Soten Technology Group'
    }

    return head
  },
  computed: {
    ...mapState(['isPC', 'isApp']),
  },
  watch: {
    $route(value, oldValue) {
      const cPath = value.fullPath.replace('/zh', '')
      const nPath = oldValue.fullPath.replace('/zh', '')

      // 当前页面语言切换
      if (cPath + nPath === '/' || cPath === nPath) {
        return
      }

      if (this.$refs.nuxtBody) {
        window.scrollTo(0, 0)
      }
    },
  },
  created() {
    this.reload() // 点击浏览器刷新按钮，由于异步获取cachedViews，组件已创建成功，但cachedViews还未有值。重新加载容器
  },
  mounted() {
    this.reRender()
    // 防抖处理函数需要绑定到this,并且与取消监听函数一致
    this.debounceFunc = debounce(this.reRender)
    window.addEventListener('resize', this.debounceFunc)
    // 防抖处理函数需要绑定到this,并且与取消监听函数一致
    this.scrollFunc = debounce(this.onScroll, 100)
    window.addEventListener('scroll', this.scrollFunc)
    // 禁止safiri 缩放
    window.onload = function () {
      document.addEventListener('touchstart', function (event) {
        if (event.touches.length > 1) {
          event.preventDefault()
        }
      })
      let lastTouchEnd = 0
      document.addEventListener(
        'touchend',
        function (event) {
          const now = new Date().getTime()
          if (now - lastTouchEnd <= 300) {
            event.preventDefault()
          }
          lastTouchEnd = now
        },
        false
      )
      document.addEventListener('gesturestart', function (event) {
        event.preventDefault()
      })
    }
  },
  destroyed() {
    window.removeEventListener('resize', this.debounceFunc)
    this.tootipTimer && this.tootipTimer.clearLoop()
  },
  methods: {
    ...mapMutations(['update']),
    reload() {
      this.isRouterAlive = false
      this.$nextTick(() => {
        this.isRouterAlive = true
      })
    },
    // 显示注册登录弹窗
    onShow(type) {
      this.visible = true
      this.type = type
    },
    async onScroll() {
      const scrollTop = window.scrollY
      this.showTotop = scrollTop > 4000
    },
    // 重新渲染,获取当前设备
    async reRender() {
      // 获取浏览器宽度
      const w =
        window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth

      // 获取当前设备信息
      const userAgent = window.navigator.userAgent.toLowerCase()

      let isPC = true

      // 判断当前设备是手机 || 当前pc浏览器宽度小于最佳浏览尺寸
      if (userAgent.includes('mobile') || w <= MIN_CLIENT_WIDTH) {
        isPC = false
      }
      this.update({
        isPC,
        isApp: !isPC,
      })
    },
    // 回到顶部
    scrollToTop() {
      const scrollElement = window // 或者使用 document.body，根据实际情况选择
      const animationDuration = 400 // 动画持续时间，以毫秒为单位

      // 使用 requestAnimationFrame 实现动画效果
      function scrollToTopAnimated(timestamp) {
        const currentTime = Date.now()
        const progress = Math.min(1, (currentTime - startTime) / animationDuration)

        scrollElement.scrollTo(0, startingYOffset - progress * startingYOffset)

        if (progress < 1) {
          requestAnimationFrame(scrollToTopAnimated)
        }
      }

      const startingYOffset = scrollElement.scrollY
      const startTime = Date.now()

      requestAnimationFrame(scrollToTopAnimated)
    },
  },
}
</script>

<style lang="less">
@import '~assets/var';

body {
  overflow-y: auto;
  height: 100vh;
}

.container {
  width: 100vw;
  display: flex;
}

#__nuxt {
  .el-container {
    overflow: hidden;
    position: relative;
    background-color: #fff;
  }

  .nuxt-main {
    display: flex;
    flex-direction: column;
    padding: 5.208vw 0 0 0;

    &.isApp {
      padding: 50px 0 0 0;
    }
  }

  .nuxt-body {
    flex: 1;
    padding: 0;
    overflow: auto;

    .totop {
      position: fixed;
      bottom: 4vh;
      z-index: 99;
      display: inline-block;
      border-radius: 50%;
      .width(50);
      .height(50);
      .left(1800);
      .lineH(50);

      text-align: center;
      background: #fff;
      box-shadow: 0 8px 16px -4px rgba(37, 48, 68, 0.16), 0 1px 3px 0 rgba(37, 48, 68, 0.12);
      transition: all 0.3s;
      transform: translateX(50%);
      opacity: 0;
      cursor: pointer;

      &.active {
        opacity: 1;
      }

      i {
        .ft(24);
      }
    }
  }
}
</style>
